package com.gaogis.platform.filter;


import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import java.io.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import org.springframework.web.util.WebUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.UUID;






@Slf4j
@Component
@WebFilter(urlPatterns = "/")
public class HttpLogFilter extends OncePerRequestFilter {
	

    public static final int MAX_BODY_BYTE_SIZE = 1500;
    public static final String LINE_BREAK_REGX = "\n";
public static final String UNKNOWN_BODY = "[unknown]";
 public static final String EQUAL_SIGN = "=";
public static final String COMMA = ",";
    @Override
    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain)throws ServletException, IOException{
	if(skip(request)){
		filterChain.doFilter(request,response);
		return;
	}

        RepeatReadHttpRequest wrapperRequest = new RepeatReadHttpRequest(request);
        ContentCachingResponseWrapper wrapperResponse = new ContentCachingResponseWrapper(response);
	String requestParams = getRequestParams(request);
	String requestBodyStr = getRequestBody(wrapperRequest);

	log.info("request info: url:{}, params: {} ,body:{}", request.getRequestURI(),requestParams,requestBodyStr);        
        filterChain.doFilter(wrapperRequest, wrapperResponse);
	wrapperResponse.copyBodyToResponse();	
    }



private static String getRequestBody(RepeatReadHttpRequest request) throws IOException {
    byte[] buf = request.readInputStream();
    String str=new String(buf, 0, Math.min(buf.length, MAX_BODY_BYTE_SIZE), request.getCharacterEncoding());
    return str;
}


private static String getResponseBody(ContentCachingResponseWrapper response) {
        ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        String payload = "";
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                try {
                    payload = new String(buf, 0, Math.min(buf.length, MAX_BODY_BYTE_SIZE), wrapper.getCharacterEncoding());
                } catch (UnsupportedEncodingException e) {
                    payload = UNKNOWN_BODY;
                }
            }
        }
        return payload;
    }



private static String getRequestParams(HttpServletRequest request) {
    StringBuilder urlParamBuilder = new StringBuilder();

    Enumeration<String> enu = request.getParameterNames();
    while (enu.hasMoreElements()) {
        String name = enu.nextElement();
        urlParamBuilder.append(name).append(EQUAL_SIGN).append(request.getParameter(name));
        if (enu.hasMoreElements()) {
            urlParamBuilder.append(COMMA);
        }
    }
    return urlParamBuilder.toString();
}





    private boolean skip(HttpServletRequest request) {
        String uri = request.getRequestURI();
        return uri==null || uri.isEmpty() || uri.endsWith(".ico") || uri.endsWith(".css") || uri.endsWith(".html")
                || uri.endsWith(".js") || uri.endsWith(".gif") || uri.endsWith(".png") || uri.endsWith(".jpg")
                || uri.endsWith(".htm") || uri.endsWith(".jpg") || uri.endsWith("tmd_status") || uri.contains("taobao");
    }


}
